/*****************************************************************************
 *   Copyright 2005 Tim A Wang
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 ****************************************************************************/
package com.jb.framework;


import com.jb.web.model.ChangeListener;
import com.jb.web.model.DBDescriptor;
import com.jb.web.model.GUID;

import java.io.Serializable;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class ModelBean implements Persistable {
    static private Log log = LogFactory.getLog(ModelBean.class.getName());
    public static int PRIVATE = 0;
    public static int PUBLIC = 2;
    public static int FRIEND = 1;

    static {
        PersistentManagerRegistry.registerDescriptor(ModelBean.class, new DBDescriptor());
    }

    private Date endDate;
    private Date startDate = Calendar.getInstance().getTime();
    private PersistentManager persistentManager;
    private String description;
    private List children = new ArrayList();

    //override this to have db descriptor at class level
    //public static PersistentDescriptor dbDescriptor = new ModelBeanDBDescriptor(pClassName);
    private String id;

    public List getChildren() {
        return children;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setId(String newId) {
        id = newId;
    }

    public String getId() {
        return id;
    }

    public void setPersistentManager(PersistentManager persistentManager) {
        this.persistentManager = persistentManager;
    }

    public PersistentManager getPersistentManager() {
        return persistentManager;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void addChild(Persistable p) {
        if(children.contains(p))
            return;
        children.add(p);
    }

    public Object clone() throws CloneNotSupportedException {
        try {
            ModelBean p = (ModelBean) getClass().newInstance();
            com.jb.framework.util.PropUtil.assignProperties(this, p);
            p.setId(GUID.next(p.getClass()));
            return p;
        } catch (InstantiationException e) {
            if(log.isErrorEnabled())
                log.error(this, e);
            
            throw new CloneNotSupportedException(e.getMessage());
        } catch (IllegalAccessException e) {
            if(log.isErrorEnabled())
                log.error(this, e);
            throw new CloneNotSupportedException(e.getMessage());
        }
    }

    public void create(PersistentContext ctx) {
        PersistentManager s = PersistentManagerRegistry.getPersistentManager(getClass());
        s.create(this);
        postCreate(ctx);

        for (int i = 0; i < PersistentManagerRegistry.changeListeners.size(); i++) {
            ChangeListener cl = (ChangeListener)PersistentManagerRegistry.changeListeners.get(i);
            cl.onCreate(ctx, this);
        }
    }

    public void delete(PersistentContext ctx) {
        PersistentManager s = PersistentManagerRegistry.getPersistentManager(getClass());
        s.delete(this);

        for (int i = 0; i < PersistentManagerRegistry.changeListeners.size(); i++) {
            ChangeListener cl = (ChangeListener)PersistentManagerRegistry.changeListeners.get(i);
            cl.onDelete(ctx, this);
        }
    }

    public boolean equals(Object obj) {
        return getClass().isInstance(obj) && (getId() != null) && getId().equals(((ModelBean) obj).getId());
    }

    public boolean load() {
        PersistentManager s = PersistentManagerRegistry.getPersistentManager(getClass());
        return s.load(this);
    }

    public void postCreate(PersistentContext ctx) {
    }

    public void update(PersistentContext ctx) {
        PersistentManager s = PersistentManagerRegistry.getPersistentManager(getClass());
        s.save(this);
        for (int i = 0; i < PersistentManagerRegistry.changeListeners.size(); i++) {
            ChangeListener cl = (ChangeListener)PersistentManagerRegistry.changeListeners.get(i);
            cl.onUpdate(ctx, this);
        }
    }
}
